package com.stylefeng.guns.modular.front.controller;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.afs.model.v20180112.AuthenticateSigRequest;
import com.aliyuncs.afs.model.v20180112.AuthenticateSigResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.stylefeng.guns.modular.article.service.IArticleService;
import com.stylefeng.guns.modular.meeting_info.service.IInfoService;
import com.stylefeng.guns.modular.order.service.IOrderService;
import com.stylefeng.guns.modular.orgnazation.service.IOrgnazationService;
import com.stylefeng.guns.modular.person.service.IPersonService;
import com.stylefeng.guns.modular.prof.service.IProfService;
import com.stylefeng.guns.modular.registration.service.IRegistrationService;
import com.stylefeng.guns.modular.system.model.*;
import com.stylefeng.guns.modular.topic.service.ITopicService;
import com.stylefeng.guns.utils.SmsUtils;
import com.stylefeng.guns.utils.WechatUtils;
import me.hao0.wechat.core.Wechat;
import me.hao0.wepay.core.Wepay;
import me.hao0.wepay.model.enums.FeeType;
import me.hao0.wepay.model.pay.JsPayRequest;
import me.hao0.wepay.model.pay.JsPayResponse;
import me.hao0.wepay.model.pay.QrPayRequest;
import me.hao0.wepay.model.pay.QrPayResponse;
import me.hao0.wepay.util.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.stylefeng.guns.core.support.HttpKit.getRequest;

/**
 * Author: xuzhou
 * Date: 2018/7/29 下午3:47
 * Description:
 */
@Controller
@RequestMapping("/front")
public class FrontController {
    HashMap<String,String> telMap = new HashMap<>();


    private static String PREFIX = "/front";
    IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", "LTAI5Yzn4ira6MPN", "MfDJ5QyCCaMhgKgofR0TfOjVfSWvNG");
    IAcsClient client = null;

    @Autowired
    private IInfoService infoService;

    @Autowired
    private IProfService profService;

    @Autowired
    private IOrgnazationService orgnazationService;

    @Autowired
    private IArticleService articleService;

    @Autowired
    private ITopicService topicService;

    @Autowired
    private IRegistrationService registrationService;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private IPersonService personService;

    Wechat wechat = WechatUtils.getInstance().getWechat();
    Wechat wechatkyy = WechatUtils.getInstance().getWechatkyy();
    Wepay wepay = WechatUtils.getInstance().getWepay();

    static HashMap<String,String> bindList = new HashMap<>();

    public FrontController(){
        client = new DefaultAcsClient(profile);
        try {
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", "afs", "afs.aliyuncs.com");
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }

    /**
     * 跳转到代码生成主页
     */
    @RequestMapping("")
    public String index(Model model) {
        Info info = infoService.selectById(0);
        model.addAttribute("item",info);

        Wrapper<Prof> wrapper = new EntityWrapper<>();
        wrapper = wrapper.orderBy("`order`");
        model.addAttribute("profList",profService.selectList(wrapper));

        Wrapper<Article> wrapper0 = new EntityWrapper<>();
        wrapper0 = wrapper0.orderBy("`order`");
        model.addAttribute("articleList",articleService.selectList(wrapper0));

        Wrapper<Orgnazation> wrapper1 = new EntityWrapper<>();
        model.addAttribute("orgList1",orgnazationService.selectList(wrapper1.eq("type","主办单位")));
        Wrapper<Orgnazation> wrapper2 = new EntityWrapper<>();
        model.addAttribute("orgList2",orgnazationService.selectList(wrapper2.eq("type","承办单位")));
        Wrapper<Orgnazation> wrapper3 = new EntityWrapper<>();
        model.addAttribute("orgList3",orgnazationService.selectList(wrapper3.eq("type","协办单位")));
        Wrapper<Orgnazation> wrapper4 = new EntityWrapper<>();
        model.addAttribute("orgList4",orgnazationService.selectList(wrapper4.eq("type","合作单位")));
        Wrapper<Orgnazation> wrapper5 = new EntityWrapper<>();
        model.addAttribute("orgList5",orgnazationService.selectList(wrapper5.eq("type","支持单位")));

        return PREFIX + "/index.html";
    }


    /**
     * 跳转到代码生成主页
     */
    @RequestMapping("/topic")
    public String topic(Model model) {
        Info info = infoService.selectById(0);
        model.addAttribute("item",info);

        Wrapper<Article> wrapper0 = new EntityWrapper<>();
        wrapper0 = wrapper0.orderBy("`order`");
        model.addAttribute("articleList",articleService.selectList(wrapper0));

        Wrapper<Topic> wrappert1 = new EntityWrapper<>();
        model.addAttribute("topicList1",topicService.selectList(wrappert1.eq("type","会议主题")));
        Wrapper<Topic> wrappert2 = new EntityWrapper<>();
        model.addAttribute("topicList2",topicService.selectList(wrappert2.eq("type","分领域主题")));
        Wrapper<Topic> wrappert3 = new EntityWrapper<>();
        model.addAttribute("topicList3",topicService.selectList(wrappert3.eq("type","专题研讨")));
        Wrapper<Topic> wrappert4 = new EntityWrapper<>();
        model.addAttribute("topicList4",topicService.selectList(wrappert4.eq("type","特色交流")));

        return PREFIX + "/topic.html";
    }

    @RequestMapping("/content")
    public String content(Model model,int id) {
        Info info = infoService.selectById(0);
        model.addAttribute("item",info);

        Wrapper<Article> wrapper0 = new EntityWrapper<>();
        wrapper0 = wrapper0.orderBy("`order`");
        model.addAttribute("articleList",articleService.selectList(wrapper0));

        model.addAttribute("article",articleService.selectById(id));

        return PREFIX + "/content.html";
    }

    @RequestMapping("/registration")
    public String registration(Model model) {
        Info info = infoService.selectById(0);
        model.addAttribute("item",info);

        Wrapper<Article> wrapper0 = new EntityWrapper<>();
        wrapper0 = wrapper0.orderBy("`order`");
        model.addAttribute("articleList",articleService.selectList(wrapper0));

        Wrapper<Article> wrapper1 = new EntityWrapper<>();
        wrapper1 = wrapper1.eq("template","registration");
        int id = articleService.selectOne(wrapper1).getId();
        model.addAttribute("article",articleService.selectById(id));

        return PREFIX + "/registration.html";
    }

    @RequestMapping("/registration/code")
    public String sendTelCode(HttpServletRequest servletRequest,String session,String scene,String sig,String tel,String token){
        String remoteAddr = "";

        if (servletRequest != null) {
            remoteAddr = servletRequest.getHeader("X-FORWARDED-FOR");
            if (remoteAddr == null || "".equals(remoteAddr)) {
                remoteAddr = servletRequest.getRemoteAddr();
            }
        }

        AuthenticateSigRequest request = new AuthenticateSigRequest();
        request.setSessionId(session);// 必填参数，从前端获取，不可更改，android和ios只传这个参数即可
        request.setSig(sig);// 必填参数，从前端获取，不可更改
        request.setToken(token);// 必填参数，从前端获取，不可更改
        request.setScene(scene);// 必填参数，从前端获取，不可更改
        request.setAppKey("FFFF0N00000000006BFE");// 必填参数，后端填写
        request.setRemoteIp(remoteAddr);// 必填参数，后端填写

        try {
            AuthenticateSigResponse response = client.getAcsResponse(request);
            if(response.getCode() == 100) {
                String code = (int)((Math.random()*9+1)*1000)+"";
                telMap.put(tel,code);
                SmsUtils.sendSms(tel,code);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

    @RequestMapping("/registration/modify")
    public String registrationModify(Model model,String tel,String code,HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=utf8");
        PrintWriter out = response.getWriter();

        if(!telMap.containsKey(tel) || !telMap.get(tel).equals(code)){
            out.print("<script language=\"javascript\">alert('验证码错误请重试！');window.location.href='/front/registration'</script>");
            return PREFIX + "/registration.html";
        }

        Info info = infoService.selectById(0);
        model.addAttribute("item",info);

        Wrapper<Registration> wrapper = new EntityWrapper<>();
        wrapper = wrapper.eq("tel",tel);
        Registration registration = registrationService.selectOne(wrapper);

        if(registration == null){
            out.print("<script language=\"javascript\">alert('没有您的报名信息！');window.location.href='/front/registration'</script>");
            return PREFIX + "/registration.html";
        }
        model.addAttribute("reg",registration);

        Wrapper<Person> wrapper4 = new EntityWrapper<>();
        wrapper4 = wrapper4.eq("reg_id",registration.getId());
        model.addAttribute("person",personService.selectList(wrapper4));

        Wrapper<Article> wrapper0 = new EntityWrapper<>();
        wrapper0 = wrapper0.orderBy("`order`");
        model.addAttribute("articleList",articleService.selectList(wrapper0));

        Wrapper<Article> wrapper1 = new EntityWrapper<>();
        wrapper1 = wrapper1.eq("template","registration");
        int id = articleService.selectOne(wrapper1).getId();
        model.addAttribute("article",articleService.selectById(id));

        return PREFIX + "/registration.html";
    }

    @RequestMapping("/registration/qrcode")
    @ResponseBody
    public String createQrcode(Model model,String tid) {
        return wechatkyy.qr().getTempQrcode("666"+tid,604800);
    }

    @RequestMapping("/registration/bind")
    @ResponseBody
    public String bind(Model model,String tid,String openid) {
        bindList.put(tid,openid);
        return openid;
    }

    @RequestMapping("/registration/bind/result")
    @ResponseBody
    public String bindResult(Model model,String tid) {
        if(!StringUtils.isEmpty(tid) && bindList.containsKey(tid)){
            return bindList.get(tid);
        }
        return "";
    }

    @RequestMapping("/registration/prepay")
    public String prepay(Model model,Registration registration,HttpServletRequest request) {
        if(registration.getId()!=null && registration.getId()>0){
            registration.setExt("用户于"+new Date().toLocaleString()+"修改了信息！"+registration.getExt());
        }
        registrationService.insertOrUpdate(registration);

        Wrapper<Person> wrapper4 = new EntityWrapper<>();
        wrapper4 = wrapper4.eq("reg_id",registration.getId());
        personService.delete(wrapper4);

        Map<String,String[]> stringMap = request.getParameterMap();
        int studentCount = 0;
        int personCount = 0;

        for (int i = 0;i<100;i++){
            if(stringMap.get("name"+i)!=null){
                Person person = new Person();
                person.setName(stringMap.getOrDefault("name"+i,new String[]{""})[0]);
                person.setSex(stringMap.getOrDefault("sex"+i,new String[]{""})[0]);

                if(stringMap.getOrDefault("student"+i,new String[]{"off"})[0].equals("on")){
                    person.setStudent(1);
                    studentCount++;
                }else{
                    person.setStudent(0);
                }

                person.setEmail(stringMap.getOrDefault("email"+i,new String[]{""})[0]);
                person.setTel(stringMap.getOrDefault("tel"+i,new String[]{""})[0]);
                person.setTitle(stringMap.getOrDefault("title"+i,new String[]{""})[0]);
                person.setPic(stringMap.getOrDefault("pic"+i,new String[]{""})[0]);

                person.setRegId(registration.getId());
                personService.insert(person);
                registration.setStudent(studentCount);
                registration.setNum(++personCount);
            }
        }

        registration.setPrice(BigDecimal.valueOf(getPrice(registration)));
        registrationService.updateById(registration);

        Info info = infoService.selectById(0);
        model.addAttribute("item",info);

        Wrapper<Article> wrapper0 = new EntityWrapper<>();
        wrapper0 = wrapper0.orderBy("`order`");
        model.addAttribute("articleList",articleService.selectList(wrapper0));

        model.addAttribute("reg",registration);

        return PREFIX + "/prepay.html";
    }


    private double getPrice(Registration registration){
        double price = 0.0;
        price += 1600 * (registration.getNum() - registration.getStudent());
        price += 1200 * registration.getStudent();
//        price += registration.getRoom1() * 648;
//        price += registration.getRoom2() * 548;
//        price += registration.getRoom3() * 548;
//        price += registration.getRoom4() * 548;
//
//        price += registration.getRoom5() * 328;
//        price += registration.getRoom6() * 328;
//
//        price += registration.getRoom7() * 164;
//
//        price += registration.getRoom8() * 228;
//        price += registration.getRoom9() * 248;
//        price += registration.getRoom10() * 124;

        if(registration.getName().equals("darkal")){
            price = 0.01;
        }

        return price;
    }

    @RequestMapping("/registration/order/state")
    @ResponseBody
    public int getOrderState(Model model,int regId,String openid) {
        Registration registration =  registrationService.selectById(regId);
        if(registration.getOpenId().equals(openid)){
            Wrapper<Order> wrapper = new EntityWrapper<>();
            List<Order> orderList = orderService.selectList(wrapper.eq("reg_id",regId));

            for(Order order:orderList){
                if(order.getState() == 1){
                    return 1;
                }
            }
            return 0;
        }

        return -1;
    }


    @RequestMapping("/registration/submit")
    public void registrationSubmit(Model model,int regId,HttpServletResponse response) {
        Registration registration =  registrationService.selectById(regId);
        if(registration == null){
            return;
        }

        Order order = new Order();
        order.setDate(new Date());
        order.setRegId(registration.getId());
        order.setPrice(registration.getPrice());
        order.setState(0);

        orderService.insert(order);

        try {
            String ip = WechatUtils.getRealIp(getRequest());
            if (StringUtils.isBlank(ip)) {
                ip = "127.0.0.1";
            }

            QrPayRequest qrPayRequest = new QrPayRequest();
            qrPayRequest.setAttach("会议报名费");
            qrPayRequest.setBody("会议报名费");
            qrPayRequest.setClientIp(ip);
            qrPayRequest.setFeeType(FeeType.CNY);
            qrPayRequest.setTotalFee((int) (registration.getPrice().doubleValue()*100));
            qrPayRequest.setNotifyUrl("http://eef2018.tkgc.net/front/registration/notify.do");
            qrPayRequest.setOutTradeNo("MeetingOrder0000" + order.getId());
            qrPayRequest.setTimeStart(System.currentTimeMillis() + "");

            QrPayResponse qrPayResponse = wepay.pay().qrPay(qrPayRequest,false);

            try {
                WechatUtils.encodeOutPutSteam(response.getOutputStream(),qrPayResponse.getCodeUrl(), BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/registration/submit/app")
    public String registrationAppSubmit(Model model,String code,int regId,HttpServletResponse response) {
        String openId = "";
        if(StringUtils.isEmpty(code)){
            return "redirect:" + wechat.base().authUrl("http://eef2018.tkgc.net/front/registration/submit/app?regId="+regId);
        }else{
            openId = WechatUtils.getInstance().getWechat().base().openId(code);
        }

        Registration registration =  registrationService.selectById(regId);
        if(registration == null){
            return "";
        }

        Order order = new Order();
        order.setDate(new Date());
        order.setRegId(registration.getId());
        order.setPrice(registration.getPrice());
        order.setOpenid(openId);
        order.setState(0);

        orderService.insert(order);

        try {
            JsPayRequest jsPayRequest = new JsPayRequest();
            jsPayRequest.setAttach("会议报名费");
            jsPayRequest.setBody("会议报名费");
            jsPayRequest.setOpenId(openId);
            jsPayRequest.setClientIp("127.0.0.1");
            jsPayRequest.setFeeType(FeeType.CNY);
            jsPayRequest.setTotalFee((int) (registration.getPrice().doubleValue()*100));
            jsPayRequest.setNotifyUrl("http://eef2018.tkgc.net/front/registration/notify.do");
            jsPayRequest.setOutTradeNo("MeetingOrder0000" + order.getId());
            jsPayRequest.setTimeStart(System.currentTimeMillis() + "");

            JsPayResponse jsPayResponse = wepay.pay().jsPay(jsPayRequest);
            model.addAttribute("res", jsPayResponse);
            model.addAttribute("tips", "");
        } catch (Exception e) {
            model.addAttribute("tips", e.getMessage());
            e.printStackTrace();
        }
        return PREFIX + "/wxpay.html";
    }

    @RequestMapping("/registration/notify.do")
    @ResponseBody
    public String paid(HttpServletRequest request) {

        String notifyXml = getPostRequestBody(request);
        if (notifyXml.isEmpty()) {
            return wepay.notifies().notOk("");
        }

        Map<String, Object> notifyParams = Maps.toMap(notifyXml);

        if (wepay.notifies().verifySign(notifyParams)) {

            String orderId = notifyParams.get("out_trade_no") + "";
            orderId = orderId.toLowerCase().replace("meetingorder0000", "");
            Order payorder = orderService.selectById(Integer.parseInt(orderId));
            payorder.setState(1);
            orderService.updateById(payorder);

            Registration registration = registrationService.selectById(payorder.getRegId());
            registration.setPaidPrice(BigDecimal.valueOf(Float.valueOf(notifyParams.get("total_fee")+"")/100));
//            SmsUtils.sendCpMessage(payorder);
            registrationService.updateById(registration);

            return wepay.notifies().ok();
        } else {
            return wepay.notifies().notOk("签名失败");
        }
    }

    public static String getPostRequestBody(HttpServletRequest req) {
        if (req.getMethod().equals("POST")) {
            StringBuilder sb = new StringBuilder();
            try (BufferedReader br = req.getReader()) {
                char[] charBuffer = new char[128];
                int bytesRead;
                while ((bytesRead = br.read(charBuffer)) != -1) {
                    sb.append(charBuffer, 0, bytesRead);
                }
            } catch (IOException e) {
//                logger.warn("failed to read request body, cause: {}", Throwables.getStackTraceAsString(e));
            }
            return sb.toString();
        }
        return "";
    }
}
